import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:crypto/crypto.dart';
import '../models/account.dart';
import '../utils/logger.dart';
import '../utils/device_utils.dart';
import 'signature_service.dart';
import 'captcha_service.dart';

class AccountService {
  final Dio _dio = Dio();
  final SignatureService _signatureService = SignatureService();
  final CaptchaService _captchaService = CaptchaService();
  
  static const String _baseUrl = 'https://mtop.damai.cn';
  static const String _loginApi = '/h5/mtop.damai.wireless.search.broadcast.list/1.0/';
  static const String _userInfoApi = '/h5/mtop.damai.user.get/1.0/';

  AccountService() {
    _setupDio();
  }

  void _setupDio() {
    _dio.options = BaseOptions(
      baseUrl: _baseUrl,
      connectTimeout: const Duration(seconds: 10),
      receiveTimeout: const Duration(seconds: 30),
      headers: {
        'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15',
        'Accept': 'application/json',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br',
        'Connection': 'keep-alive',
      },
    );

    // 添加请求拦截器
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        AppLogger.debug('Request: ${options.method} ${options.uri}');
        handler.next(options);
      },
      onResponse: (response, handler) {
        AppLogger.debug('Response: ${response.statusCode} ${response.requestOptions.uri}');
        handler.next(response);
      },
      onError: (error, handler) {
        AppLogger.error('Request error: ${error.message}', error);
        handler.next(error);
      },
    ));
  }

  Future<LoginResult> login(Account account) async {
    try {
      AppLogger.info('Attempting login for account: ${account.username}');
      
      // 第一步：获取登录页面和必要的token
      final loginPageResult = await _getLoginPage(account);
      if (!loginPageResult.success) {
        return LoginResult(
          success: false,
          message: loginPageResult.message,
        );
      }

      // 第二步：处理验证码（如果需要）
      String? captchaResult;
      if (loginPageResult.needCaptcha) {
        captchaResult = await _handleCaptcha(loginPageResult.captchaImage!);
        if (captchaResult == null) {
          return LoginResult(
            success: false,
            message: '验证码识别失败',
          );
        }
      }

      // 第三步：提交登录请求
      final loginResult = await _submitLogin(
        account: account,
        token: loginPageResult.token!,
        captcha: captchaResult,
      );

      if (loginResult.success) {
        // 第四步：验证登录状态
        final userInfo = await _getUserInfo(loginResult.cookies!);
        if (userInfo != null) {
          return LoginResult(
            success: true,
            message: '登录成功',
            cookies: loginResult.cookies,
            token: loginResult.token,
            userInfo: userInfo,
          );
        }
      }

      return loginResult;
    } catch (e) {
      AppLogger.error('Login failed for account: ${account.username}', e);
      return LoginResult(
        success: false,
        message: '登录异常: $e',
      );
    }
  }

  Future<LoginPageResult> _getLoginPage(Account account) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final deviceInfo = await DeviceUtils.getDeviceInfo();
      
      final headers = {
        'X-DEVICE-ID': account.deviceId,
        'X-T': timestamp.toString(),
        'X-APP-KEY': '12574478',
        'X-UMID': await DeviceUtils.generateUmid(account.deviceId),
      };

      final response = await _dio.get(
        '/h5/mtop.damai.login.getloginpage/1.0/',
        options: Options(headers: headers),
      );

      if (response.statusCode == 200) {
        final data = response.data;
        
        return LoginPageResult(
          success: true,
          token: data['data']?['token'],
          needCaptcha: data['data']?['needCaptcha'] ?? false,
          captchaImage: data['data']?['captchaImage'],
        );
      }

      return LoginPageResult(
        success: false,
        message: '获取登录页面失败',
      );
    } catch (e) {
      return LoginPageResult(
        success: false,
        message: '获取登录页面异常: $e',
      );
    }
  }

  Future<String?> _handleCaptcha(String captchaImage) async {
    try {
      // 解码base64图片
      final imageBytes = base64Decode(captchaImage);
      
      // 使用验证码识别服务
      final result = await _captchaService.recognizeCaptcha(imageBytes);
      
      if (result.success && result.text != null) {
        AppLogger.info('Captcha recognized: ${result.text}');
        return result.text;
      }
      
      AppLogger.warning('Captcha recognition failed: ${result.message}');
      return null;
    } catch (e) {
      AppLogger.error('Captcha handling error', e);
      return null;
    }
  }

  Future<LoginResult> _submitLogin({
    required Account account,
    required String token,
    String? captcha,
  }) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      
      final params = {
        'loginId': account.username,
        'password': _encryptPassword(account.password),
        'token': token,
        if (captcha != null) 'captcha': captcha,
      };

      // 生成签名
      final signature = await _signatureService.generateSignature(
        params: params,
        deviceId: account.deviceId,
        timestamp: timestamp,
      );

      final headers = {
        'X-DEVICE-ID': account.deviceId,
        'X-T': timestamp.toString(),
        'X-APP-KEY': '12574478',
        'X-SIGN': signature,
        'X-UMID': await DeviceUtils.generateUmid(account.deviceId),
        'Content-Type': 'application/x-www-form-urlencoded',
      };

      final response = await _dio.post(
        '/h5/mtop.damai.login.login/1.0/',
        data: params,
        options: Options(headers: headers),
      );

      if (response.statusCode == 200) {
        final data = response.data;
        
        if (data['ret']?[0] == 'SUCCESS::调用成功') {
          // 提取cookies
          final cookies = _extractCookies(response);
          
          return LoginResult(
            success: true,
            message: '登录成功',
            cookies: cookies,
            token: data['data']?['token'],
          );
        } else {
          return LoginResult(
            success: false,
            message: data['ret']?[1] ?? '登录失败',
          );
        }
      }

      return LoginResult(
        success: false,
        message: '登录请求失败',
      );
    } catch (e) {
      return LoginResult(
        success: false,
        message: '登录请求异常: $e',
      );
    }
  }

  Future<Map<String, dynamic>?> _getUserInfo(Map<String, String> cookies) async {
    try {
      final cookieString = cookies.entries
          .map((e) => '${e.key}=${e.value}')
          .join('; ');

      final response = await _dio.get(
        _userInfoApi,
        options: Options(
          headers: {'Cookie': cookieString},
        ),
      );

      if (response.statusCode == 200) {
        final data = response.data;
        if (data['ret']?[0] == 'SUCCESS::调用成功') {
          return data['data'];
        }
      }

      return null;
    } catch (e) {
      AppLogger.error('Get user info failed', e);
      return null;
    }
  }

  String _encryptPassword(String password) {
    // 简单的密码加密，实际应用中应该使用更安全的方法
    final bytes = utf8.encode(password);
    final digest = sha256.convert(bytes);
    return digest.toString();
  }

  Map<String, String> _extractCookies(Response response) {
    final cookies = <String, String>{};
    
    final setCookieHeaders = response.headers['set-cookie'];
    if (setCookieHeaders != null) {
      for (final cookieHeader in setCookieHeaders) {
        final cookie = Cookie.fromSetCookieValue(cookieHeader);
        cookies[cookie.name] = cookie.value;
      }
    }
    
    return cookies;
  }

  Future<List<Map<String, dynamic>>> importFromFile(String filePath) async {
    try {
      final file = File(filePath);
      if (!await file.exists()) {
        throw Exception('文件不存在');
      }

      final content = await file.readAsString();
      final accounts = <Map<String, dynamic>>[];

      // 支持多种格式
      if (filePath.endsWith('.json')) {
        // JSON格式
        final jsonData = jsonDecode(content);
        if (jsonData is List) {
          accounts.addAll(jsonData.cast<Map<String, dynamic>>());
        }
      } else if (filePath.endsWith('.txt') || filePath.endsWith('.csv')) {
        // 文本格式：username:password 或 username,password
        final lines = content.split('\n');
        for (final line in lines) {
          final trimmed = line.trim();
          if (trimmed.isNotEmpty) {
            final parts = trimmed.contains(':') 
                ? trimmed.split(':')
                : trimmed.split(',');
            
            if (parts.length >= 2) {
              accounts.add({
                'username': parts[0].trim(),
                'password': parts[1].trim(),
                'phone': parts.length > 2 ? parts[2].trim() : null,
                'email': parts.length > 3 ? parts[3].trim() : null,
              });
            }
          }
        }
      }

      AppLogger.info('Imported ${accounts.length} accounts from file');
      return accounts;
    } catch (e) {
      AppLogger.error('Import accounts from file failed', e);
      throw Exception('导入账号失败: $e');
    }
  }

  Future<bool> validateAccount(Account account) async {
    try {
      final loginResult = await login(account);
      return loginResult.success;
    } catch (e) {
      AppLogger.error('Validate account failed', e);
      return false;
    }
  }
}

class LoginResult {
  final bool success;
  final String? message;
  final Map<String, String>? cookies;
  final String? token;
  final Map<String, dynamic>? userInfo;

  LoginResult({
    required this.success,
    this.message,
    this.cookies,
    this.token,
    this.userInfo,
  });
}

class LoginPageResult {
  final bool success;
  final String? message;
  final String? token;
  final bool needCaptcha;
  final String? captchaImage;

  LoginPageResult({
    required this.success,
    this.message,
    this.token,
    this.needCaptcha = false,
    this.captchaImage,
  });
}